package ar.com.spsolutions.splibrary.book;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import ar.com.spsolutions.splibrary.entity.Entity;
import ar.com.spsolutions.splibrary.notifiers.INotifier;
import ar.com.spsolutions.splibrary.user.User;
import ar.com.spsolutions.splibrary.utils.DateUtil;

public class LoanBook extends Entity {
	private static final long serialVersionUID = -2206698761178345869L;

	private static final int EXCEEDED_DAYS = 4;

	private static final int MAX_REFUN_TIME = 14;

	private BookCopy copy;

	private DateTime loanDate = new DateTime();

	private DateTime expirationDate;

	private DateTime refundDate;

	private User user;

	private INotifier notifier;

	private boolean notified;

	public LoanBook() {
		super();
		this.setNotified(false);
	}

	public LoanBook(final User customer, final BookCopy aCopy) {
		this();
		this.user = customer;
		this.user.addLoan(this);
		this.copy = aCopy;
		aCopy.setLoan(this);
		this.expirationDate = this.calculateExpirationDate();
		aCopy.getBook().incrementLoanedTimes();
	}

	private DateTime calculateExpirationDate() {
		final DateTime stimated = new DateTime()
				.plusDays(LoanBook.MAX_REFUN_TIME);
		final LocalDate laboralDate = DateUtil.getLaboralDate(stimated
				.toLocalDate());
		return DateUtil.toDateTime(laboralDate);
	}

	public boolean isDue() {

		return !this.isRefun() || this.isLoanDue();
	}

	private boolean isLoanDue() {
		final DateTime exeedDate = this.getExpirationDate().plusDays(
				LoanBook.EXCEEDED_DAYS);
		final LocalDate laboralDate = DateUtil.getLaboralDate(new LocalDate(
				exeedDate));
		return DateUtil.toDateTime(laboralDate).isBeforeNow();
	}

	public boolean isRefun() {
		return this.getRefundDate() != null;
	}

	public void setRefun(final boolean refun) {
		// stub
	}

	public String bookTitle() {
		return this.getCopy().getTitle();
	}

	// --accesors---

	public BookCopy getCopy() {
		return this.copy;
	}

	public void setCopy(final BookCopy copy) {
		this.copy = copy;
	}

	public DateTime getLoanDate() {
		return this.loanDate;
	}

	public void setLoanDate(final DateTime loanDate) {
		this.loanDate = loanDate;
	}

	public DateTime getRefundDate() {
		return this.refundDate;
	}

	public void setRefundDate(final DateTime refundDate) {
		this.refundDate = refundDate;
	}

	public User getUser() {
		return this.user;
	}

	public void setUser(final User user) {
		this.user = user;
	}

	public void notifyLoan() {
		this.getNotifier().setRecipient(this.getUser());
		this.getNotifier().setSubject("Aviso de alquiler");
		final String mailMessage = "Estimado %s\n\t"
				+ "SPLibrary le informa que el alquiler del libro %s tiene como fecha de vencimiento %s.\n\n"
				+ "El equipo de SPLibrary splibrary.develop@gmail.com";
		this.getNotifier().setMessage(
				String.format(mailMessage, this.getUser().getName(), this
						.getCopy().getTitle(), DateUtil.format(this
						.getExpirationDate())));
		this.getNotifier().sendNotification();
	}

	public void refun() {
		this.setRefundDate(new DateTime());
		this.getCopy().refun();
		this.getUser().refunLoan(this);
		this.notifyBookRefun();
	}

	private void notifyBookRefun() {
		this.getNotifier().setRecipient(this.getUser());
		this.getNotifier().setSubject("Aviso de devolucion");
		final String mailMessage = "Estimado %s\n\t"
				+ "SPLibrary le informa que el  %s fue devuelto el dia %s.\n\n"
				+ "El equipo de SPLibrary splibrary.develop@gmail.com";
		this.getNotifier().setMessage(
				String.format(mailMessage, this.getUser().getName(), this
						.getCopy().getTitle(), DateUtil.format(this
						.getRefundDate())));
		this.getNotifier().sendNotification();

	}

	public void notifyBookDue() {
		this.getNotifier().setRecipient(this.getUser());
		this.getNotifier().setSubject("Aviso de vencimiento");
		final String mailMessage = "Estimado %s\n\t"
				+ "SPLibrary le informa que el prestamo del libro %s vencio el %s y debera devolverlo a la brevedad.\n\n"
				+ "El equipo de SPLibrary splibrary.develop@gmail.com";
		this.getNotifier().setMessage(
				String.format(mailMessage, this.getUser().getName(), this
						.getCopy().getTitle(), DateUtil.format(this
						.getRefundDate())));
		this.getNotifier().sendNotification();
		this.setNotified(true);
	}

	public INotifier getNotifier() {
		return this.notifier;
	}

	public void setNotifier(final INotifier notifier) {
		this.notifier = notifier;
	}

	public DateTime getExpirationDate() {
		return this.expirationDate;
	}

	public void setExpirationDate(final DateTime expirationDate) {
		this.expirationDate = expirationDate;
	}

	public boolean isNotified() {
		return this.notified;
	}

	public void setNotified(final boolean notiefied) {
		this.notified = notiefied;
	}

}
